package pers.cyril.jdb.server.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;
import pers.cyril.jdb.protocol.codec.PacketCodeCHandler;
import pers.cyril.jdb.protocol.codec.PacketSpliter;
import pers.cyril.jdb.server.config.ServerConfig;
import pers.cyril.jdb.server.netty.handler.CheckSessionHandler;
import pers.cyril.jdb.server.netty.handler.CreateDatabaseRequestHandler;
import pers.cyril.jdb.server.netty.handler.IdleStateCheckHandler;
import pers.cyril.jdb.server.netty.handler.LoginRequestHandler;

import java.util.concurrent.TimeUnit;

/**
 * 说点什么吧
 *
 * @author Wang Cyril
 * @date 2024/5/24 20:27
 */
@Slf4j
public class NettyServer {

    private String host;
    private int port;

    public NettyServer(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) {
                        ch.pipeline().addLast(new IdleStateCheckHandler(ServerConfig.INSTANCE.connectionReadIdleTime
                                , ServerConfig.INSTANCE.connectionWriteIdleTime
                                , ServerConfig.INSTANCE.connectionAllIdleTime, TimeUnit.MILLISECONDS));
                        ch.pipeline().addLast(new PacketSpliter());
                        ch.pipeline().addLast(PacketCodeCHandler.INSTANCE);
                        ch.pipeline().addLast(LoginRequestHandler.INSTANCE);
                        ch.pipeline().addLast(CheckSessionHandler.INSTANCE);
                        ch.pipeline().addLast(CreateDatabaseRequestHandler.INSTANCE);
                    }
                });

        serverBootstrap.bind(host, port).addListener(new GenericFutureListener<Future<? super Void>>() {
            @Override
            public void operationComplete(Future<? super Void> future) throws Exception {
                if (future.isSuccess()) {
                    log.info("jdb服务启动成功，port={}", port);
                } else {
                    log.error("jdb服务启动失败，port={}", port);
                }
            }
        });
    }
}
